#! /bin/sh
# This is a shell archive. To extract the files type 'sh file'
# This archive created on Thu Jun 21 16:37:30 WET DST 1990\n
export PATH; PATH=/bin:$PATH
echo 'Shar: extracting 'README' ( 4338 characters)'
if test -f 'README'
then
    echo "Shar: will not overwrite existing file 'README'"
else
    cat << \SHAR_EOF > 'README'
FRACTALS - July 1989.
--------- -----------

Author:		Paul Sharpe @ DEC, Reading, England.
Inspiration:	Title:		"The Science Of Fractal Images."
		Editors:	Heinz-Otto Peitgen, Dietmar Saupe
		Published:	Springer-Verlag

>>> Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
>>> Copyright is claimed in the computer program and user interface thereof.

>>> Digital Equipment Corporation cannot accept any responsibility for
>>> use, misuse, or abuse of this software.

>>> The code is provided as-is. No guarantee is made to provide support or
>>> maintenance.
>>> This said, the code may be used in any way, on the provisos:
>>> 1 - The author and the authors company can not accept any responsibilty
>>>     for the use/misuse/abuse of the software.
>>> 2 - The credits/copyrights at the top of the files remain.
>>> Any suggestions/improvements/bug-reports will be at least read.

This code was written under Ultrix(c) on a Vaxstation II GPX, with 8-plane
colour, using DECwindows. It should work on 'any' UNIX(c), with X11
derivatives and with 1 or more colour planes...

It has been tested on a DECuVax II GPX (8-plane), a DS3100 (8-plane)
and a Sun 3/50 (1-plane)
It requires the X11 library, though probably not necessarily release 3.

To compile, edit the Makefile and configure the compiler options: in
particular, change the paths to find the bitmaps for the icon and the
background.
Then just type 'make'.



Fractal mountains in 3D, by brownian motion.
--------------------------------------------

It was mainly written with a colour capacity in mind, but allows the colours
on the command line to be set for monochrome dispays:

e.g. for monochrome: xmntn -ba black -mn black -se black)

Use 'xmntn -help' for a full list of options.

There is a simple interaction to allow new generations of mountain data without
having to quit and restart: simply click any mouse button in the pointer window
at the point along the scale for the dimension. The scale is graduated at the
integer values 1.00 and 2.00, and the scale allows for values entered up to
3.00. Clicking on the 'New Mountains' window will cause new data to be
generated and the mountains drawn. On a lowly GPX, this takes 30 seconds or
so for each phase. On a MIPS box, its INSTANT!

There is an alternative perspective to the mountains shown by the executable
'xlmntn'. This attempts to bring the viewer down to the level of the
mountains. It takes many of the same options, but also allows for the distance
of the observer to be changed.

There are lots of arguments, but 'sensible' defaults are provided that allow
you to just run the program. Most options are self-explanatory: others are
not really to be changed. The general idea is to just play with them!

xmntn|xlmntn
	-display display-string	(default: "")
	-foreground colour	(default: white)
	-background colour	(default: red)
	-textfg colour		(default: white)
	-textbg colour 		(default: blue)
	-seacolour  colour	(default: blue)
	-mntncolour colour	(default: forestgreen)
	-numcolours integer	(default: 50)
	-colour r,g,b		(default: g)		<i.e. any of r,g,b>
	-fontfile fontfile	(default: )
	-H double		(default: 0.9)
	-scale double		(default: 2.5)
	-level integer		(default: 7)

	-mntndistance integer	(default: 100)		<xlmntn only>
	-scrndistance integer	(default: 500)		<xlmntn only>
	-height integer		(default: 120)		<xlmntn only>

	-xscale integer		(default: 4)		<xmntn only>
	-yscale integer		(default: 2)		<xmntn only>

Restrictions/Things To Do:
--------------------------
o Each program, when using full colour, installs a local colourmap for its
main window: this has the 'disturbing' effect of changing the colours of
existing applications. This is only for the lifetime of these fractal
programs, and only while they are currently in focus... This should
negociate/cooperate with the window-manager...

o Small level numbers (<4) cause there to be not enough width for the
'buttons' and 'labels', which then overlap. They should try harder at
fitting, or should be re-sized, or re-prioritised... Maybe the font
should be made smaller...

o There should be a visible indication of when any of the 'buttons' are
clicked upon...

o Better behaviour on having areas exposed: redrawing the entire region
is not a good idea on slow systems.

Any problems to sharpe@wessex.co.uk
SHAR_EOF
if test 4338 -ne `wc -c < 'README'`
then
    echo 'Shar: error transmitting 'README' (should have been  4338 charcaters)'
fi
fi
echo 'Shar: extracting 'Makefile' ( 1223 characters)'
if test -f 'Makefile'
then
    echo "Shar: will not overwrite existing file 'Makefile'"
else
    cat << \SHAR_EOF > 'Makefile'
###############################################################################
#*
#*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
#*   Copyright is claimed in the computer program and user interface thereof.
#*
#*   Digital Equipment Corporation cannot accept any responsibility for
#*   use, misuse, or abuse of this software.
#*
###############################################################################

ICONFILE= -DICONFILE="\"/eueg/valmar1/pjs/src/MNTNS/mntn.btm\""
BCKGFILE= -DBCKGRND="\"/eueg/valmar1/pjs/src/MNTNS/bg.btm\""
CFLAGS= -O ${ICONFILE} ${BCKGFILE}

STRIP=touch

HFILES= xpt.h xlmntn.h xmntn.h

CMNO=	xpt.o gen_mntndata.o cmn_mntncode.o
CMNC=	xpt.c gen_mntndata.c cmn_mntncode.c
XLO=	xlmntn.o
XLC=	xlmntn.c
XO=	xmntn.o
XC=	xmntn.c

BTMS=	bg.btm mntn.btm

SHAR= xmntns.sh

PROGS = xmntn xlmntn

X11=	-lX11

all:	${PROGS}

xmntn:	${CMNO} ${XO}
	cc -O -o $@ ${CMNO} ${XO} ${X11} -lm
	@${STRIP} $@
	@ls -l $@

xlmntn:	${CMNO} ${XLO}
	cc -O -o $@ ${CMNO} ${XLO} ${X11} -lm
	@${STRIP} $@
	@ls -l $@

xpt.o:		xpt.h
xmntn.o:	xmntn.h
xlmntn.o:	xlmntn.h

clean:
	rm -f *.o ${PROGS} core

shar:
	shar README Makefile ${HFILES} ${CMNC} ${XC} ${XLC} ${BTMS} > ${SHAR}
	@ls -l ${SHAR}
SHAR_EOF
if test 1223 -ne `wc -c < 'Makefile'`
then
    echo 'Shar: error transmitting 'Makefile' (should have been  1223 charcaters)'
fi
fi
echo 'Shar: extracting 'xpt.h' ( 1211 characters)'
if test -f 'xpt.h'
then
    echo "Shar: will not overwrite existing file 'xpt.h'"
else
    cat << \SHAR_EOF > 'xpt.h'
/*****************************************************************************
/* FILE         : xpt.h
/* DATE         : August 25, 1989.
/* AUTHOR       : Paul Sharpe @ DEC, Reading (OSCR-Europe).
/* FUNCTION     : header file to 'toolkit' of common functions.
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

#define DEFDSPLY        "unix:0.0"

#define DEBUG(x)        {printf x; fflush(stdout);}
#define ROOTWNDW(d)	RootWindow((d),DefaultScreen((d)))
#define DEFDEPTH(d)	DefaultDepth((d),DefaultScreen((d)));

#define TRUE	1
#define ON	1
#define YES	1
#define	SET	1

#define	FALSE	0
#define OFF	0
#define NO	0
#define UNSET	0

#define ARGS(X)	(args[(X)].valstr)
struct opts {
    char        flagstr[32];	/* Full argument flag string */
    char	aflagstr[8];	/* Abbreviated argument flag string */
    char	*valstr;	/* Argument command line value. */
    char	*usage;		/* Usage descriptor. */
};
SHAR_EOF
if test 1211 -ne `wc -c < 'xpt.h'`
then
    echo 'Shar: error transmitting 'xpt.h' (should have been  1211 charcaters)'
fi
fi
echo 'Shar: extracting 'xlmntn.h' ( 2546 characters)'
if test -f 'xlmntn.h'
then
    echo "Shar: will not overwrite existing file 'xlmntn.h'"
else
    cat << \SHAR_EOF > 'xlmntn.h'
/*****************************************************************************
/* FILE		: xlmntn.h
/* AUTHOR	: Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
/* DATE		: July 20, 1989
/* FUNCTION	: X-windows Fractal Brownian-Motion mountains.
/* INSPIRATION	: 'The Science Of Fractal Images.'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

/*****************************************/
/* CONFIGURE THIS SECTION AS REQUIRED... */
/*****************************************/

#define FNTFILE         "fg-18"
#define PROGTITLE	"Xlmntn"

/* The argument list processing structure... */
#define NUMARGS	16
struct opts	args[NUMARGS] = {
{"-display",	"-ds", "",		"-display serverstring"},
{"-foreground", "-fg", "white",		"-foreground colour"},
{"-background", "-bg", "red",		"-background colour"},
{"-textfg",  	"-tf", "white",		"-textfg  colour"},
{"-textbg",  	"-tb", "blue",		"-textbg  colour"},
{"-seacolour",  "-sc", "blue",		"-seacolour  colour"},
{"-mntncolour", "-mc", "forestgreen",	"-mntncolour colour"},
{"-numcolours", "-nc", "50",		"-numcolours integer"},
{"-colours",	"-cl", "g",		"-colours r|g|b"},
{"-fontfile",	"-fn", FNTFILE,		"-fontfile fontfile"},
{"-H",		"-hg", "0.9",		"-H double"},
{"-scale", 	"-sl", "2.5",		"-scale double"},
{"-level",	"-lv", "7",		"-level integer[3-~8]"},
{"-mntndistance","-md", "100",		"-mntndistance integer"},
{"-scrndistance","-sd", "500",		"-scrndistance integer"},
{"-height",	"-ht", "120",		"-height  integer"},
};

/*****************************************/
/* END OF CONFIGURATION SECTION...       */
/*****************************************/

#define PNTS(i,px,py)    {pnts[(i)].x=(px);pnts[(i)].y=(py);}
#define PIXELX(x,y)	((((x)-square/2)*scrndist)/(mntndist+(y))+(screenwidth/2))
#define	PIXELY(x,y,e)	(zeroy - ((e)-obsheight)*scrndist/(mntndist+(y)))

char    *progtitle = PROGTITLE;
char    *bckgrnd   = BCKGRND;
char    *iconfile  = ICONFILE;

int     zeroy;
int     obsheight;
int	scrndist, mntndist;

extern int	screenwidth, screenheight;
extern int	square, yscale;
extern struct mntn {
    double      **elevs;
    int         **px;
    int         **py;
} mntndata;
extern int	basey;
extern Window	wndw;
extern GC	maingc, seagc;
extern Display	*dsply;
extern long	mc;
SHAR_EOF
if test 2546 -ne `wc -c < 'xlmntn.h'`
then
    echo 'Shar: error transmitting 'xlmntn.h' (should have been  2546 charcaters)'
fi
fi
echo 'Shar: extracting 'xmntn.h' ( 2490 characters)'
if test -f 'xmntn.h'
then
    echo "Shar: will not overwrite existing file 'xmntn.h'"
else
    cat << \SHAR_EOF > 'xmntn.h'
/*****************************************************************************
/* FILE		: xmntn.h
/* AUTHOR	: Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
/* DATE		: July 20, 1989
/* FUNCTION	: X-windows Fractal Brownian-Motion mountains.
/* INSPIRATION	: 'The Science Of Fractal Images.'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

/*****************************************/
/* CONFIGURE THIS SECTION AS REQUIRED... */
/*****************************************/

#define FNTFILE         "fixed"
#define PROGTITLE	"Xmntn"

/* The argument list processing structure... */
#define NUMARGS	15
struct opts	args[NUMARGS] = {
{"-display",	"-ds", "",		"-display serverstring"},
{"-foreground", "-fg", "white",		"-foreground colour"},
{"-background", "-bg", "red",		"-background colour"},
{"-textfg",  	"-tf", "white",		"-textfg  colour"},
{"-textbg",  	"-tb", "blue",		"-textbg  colour"},
{"-seacolour",  "-sc", "blue",		"-seacolour  colour"},
{"-mntncolour", "-mc", "forestgreen",	"-mntncolour colour"},
{"-numcolours", "-nc", "50",		"-numcolours integer"},
{"-colours",  	"-cl", "g",		"-colours r|g|b"},
{"-fontfile",	"-fn", FNTFILE,		"-fontfile fontfile"},
{"-H",		"-hg", "0.9",		"-H double"},
{"-scale", 	"-sl", "2.5",		"-scale double"},
{"-level",  	"-lv", "6",		"-level integer[3-~8]"},
{"-xscale",	"-sx", "4",		"-xscale integer[1-4]"},
{"-yscale",	"-sy", "2",		"-yscale integer[1-4]"},
};

#define XOFFSET         0
#define YOFFSET         0
#define HEIGHT          5

/*****************************************/
/* END OF CONFIGURATION SECTION...       */
/*****************************************/

#define PNTS(i,px,py)    {pnts[(i)].x=(px);pnts[(i)].y=(py);}
#define PIXELX(x,y)	(XOFFSET + (square - (x) + (y)) * xscale)
#define	PIXELY(x,y)	(basey - YOFFSET - (square-(x)+square-(y))*yscale)

char	*progtitle = PROGTITLE;
char	*bckgrnd   = BCKGRND;
char	*iconfile  = ICONFILE;

extern int	screenwidth, screenheight;
extern int	square;
extern struct mntn {
    double      **elevs;
    int         **px;
    int         **py;
} mntndata;
extern int	basey;
extern Window	wndw;
extern GC	maingc, seagc;
extern Display	*dsply;
extern long	mc;

int	xscale, yscale;
SHAR_EOF
if test 2490 -ne `wc -c < 'xmntn.h'`
then
    echo 'Shar: error transmitting 'xmntn.h' (should have been  2490 charcaters)'
fi
fi
echo 'Shar: extracting 'xpt.c' ( 4720 characters)'
if test -f 'xpt.c'
then
    echo "Shar: will not overwrite existing file 'xpt.c'"
else
    cat << \SHAR_EOF > 'xpt.c'
/*****************************************************************************
/* FILE		: xpt.c
/* DATE		: August 25, 1989.
/* AUTHOR	: Paul Sharpe @ DEC, Reading (OSCR-Europe).
/* FUNCTION	: 'toolkit' of common functions.
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include "xpt.h"

char	*prog;

Display *
xpt_open_display(str)
char	*str;
{
extern char	*getenv();
Display		*dsply;

    if (str == (char *)NULL || *str == '\0')
	if ((str = getenv("DISPLAY")) == NULL)
	    str = DEFDSPLY;
    dsply = XOpenDisplay(str);
    if (dsply == (Display *)NULL) {
	fprintf(stderr,"Sorry - can't open display '%s'\n",str);
	exit(1);
    }
    return(dsply);
}

xpt_getargs(args, numargs, argc,argv)
struct	opts	args[];
int		numargs;
int		argc;
char		*argv[];
{
int	i, gotflag = 0;

    prog = *argv;
    while (--argc > 0) {
	gotflag = 0;
	if (**++argv != '-')
	    xpt_usage(args,numargs,"Value with no flag: %s",*argv);
	for (i=0; i<numargs; i++) {
	    if (strncmp(*argv,args[i].flagstr,strlen(*argv))==0 ||
	        strcmp(*argv,args[i].aflagstr)==0) {

/* Have we already had a match for this argument string ? */
		if (gotflag == 1)
		    xpt_usage(args,numargs,"Ambiguous flag: %s",*argv);
		if (args[i].valstr != (char *)TRUE && args[i].valstr != (char *)FALSE) {
/* We want an argument value from the next argv component. */
		    ++argv;
		    if (--argc <= 0)
			xpt_usage(args,numargs,"Flag with no value: %s",*argv);
		    args[i].valstr = *argv;
		}
		gotflag = 1;
	    }
	}
	if (gotflag == 0)
	    xpt_usage(args,numargs,"Unknown flag: %s",*argv);
    }
}

xpt_usage(args,numargs, fmt,str)
struct opts	args[];
int		numargs;
char		*fmt, *str;
{
int	i;

    fprintf(stderr,fmt,str);
    fprintf(stderr,"\nUsage: %s \n",prog);
    for (i=0; i<numargs; i++)
	fprintf(stderr,"           %s\n",args[i].usage);
    exit(1);
}

Window
xpt_window(dsply,parent,x,y,sx,sy,mask)
Display	*dsply;
Window	parent;
int	x,y,sx,sy,mask;
{
Window			new;
XSetWindowAttributes	attrs;

    attrs.event_mask = mask | ExposureMask;

    new = XCreateWindow(dsply,parent,x,y,sx,sy,2,DefaultDepth(dsply,DefaultScreen(dsply)),InputOutput,CopyFromParent,CWEventMask,&attrs);
    if (new == (Window)NULL) {
	fprintf(stderr,"FATAL: Couldn't create window.\n");
	exit(1);
    }
    return(new);
}

xpt_colour(dsply,name,clmap)
Display		*dsply;
char 		*name;
Colormap	clmap;
{
XColor		colour;
static Colormap	defclmap = NULL;

    if (defclmap == (Colormap)NULL)
	defclmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dsply));
    if (clmap == (Colormap)NULL)
	clmap = defclmap;

    if (XParseColor(dsply,clmap,name,&colour) == BadColor) {
	fprintf(stderr,"WARNING: Failed to parse colour '%s'...\n",name);
	return(0);
    }
    if (XAllocColor(dsply,clmap,&colour) == 0) {
	fprintf(stderr,"FATAL: Failed to alloc colour '%s'...\n",name);
	exit(1);
    }
    return(colour.pixel);
}

xpt_windowcols(dsply,wndw,gc,clmap,bg,bd,tile)
Display		*dsply;
Window		wndw;
GC		gc;
Colormap	clmap;
char		*bg, *bd, *tile;
{
    if (bg != (char *)NULL && *bg != '\0');
	XSetWindowBackground(dsply,wndw,xpt_colour(dsply,bg,clmap));
    if (bd != (char *)NULL && *bd != '\0');
	XSetWindowBorder(dsply,wndw,xpt_colour(dsply,bd,clmap));
    xpt_tile(dsply,wndw,gc,tile);
}

/* Read a bitmap: if colour, convert to a pixmap; set to window background. */
xpt_tile(dsply,wndw,gc,file)
Display	*dsply;
Window	wndw;
GC	gc;
char	*file;
{
int	h,w,x,y, depth;
Pixmap	b, pix;

    if (file == (char *)NULL || *file == '\0')
	return;
    if (XReadBitmapFile(dsply,wndw,file,&w,&h,&b,&x,&y) != BitmapSuccess) {
	fprintf(stderr,"WARNING: Can't load background bitmap '%s'.\n",file);
	return;
    }
    if ((depth = DefaultDepth(dsply,DefaultScreen(dsply))) == 1)
	XSetWindowBackgroundPixmap(dsply,wndw,b);
    else {
	pix = XCreatePixmap(dsply,wndw,w,h,depth);
	XCopyPlane(dsply,b,pix,gc,0,0,w,h,0,0,1);
	XSetWindowBackgroundPixmap(dsply,wndw,pix);
	XFreePixmap(dsply,pix);
    }
}

xpt_icon(dsply,wndw,title,iconfile)
Display	*dsply;
Window	wndw;
char	*title, *iconfile;
{
Pixmap	b;
int	h,w,x,y;
char	name[1][256];

    strcpy(name[0],title);
    if (XReadBitmapFile(dsply,wndw,iconfile,&w,&h,&b,&x,&y) != BitmapSuccess)
	fprintf(stderr,"WARNING: Can't load icon bitmap '%s'.\n",iconfile);
    else
	XSetStandardProperties(dsply,wndw,*name,*name,b,name,0,NULL);
}
SHAR_EOF
if test 4720 -ne `wc -c < 'xpt.c'`
then
    echo 'Shar: error transmitting 'xpt.c' (should have been  4720 charcaters)'
fi
fi
echo 'Shar: extracting 'gen_mntndata.c' ( 4450 characters)'
if test -f 'gen_mntndata.c'
then
    echo "Shar: will not overwrite existing file 'gen_mntndata.c'"
else
    cat << \SHAR_EOF > 'gen_mntndata.c'
/****************************************************************************
/* FILE:	gen_mntndata.c
/* AUTHOR:	Paul Sharpe @ DEC, OSCR_Europe, reading, England.
/* DATE:	October 11, 1989.
/* INSPIRATION:	'The Science Of factal Images'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/****************************************************************************/

#include <stdio.h>
#include <math.h>

#include "xpt.h"

#define F3(delta,x0,x1,x2)      ((x0+x1+x2)/3 + delta*Gauss())
#define F4(delta,x0,x1,x2,x3)   ((x0+x1+x2+x3)/4 + delta*Gauss())

int		level;
char		addition = 1;
double		sigma, H;
static int	Nrand, Arand;
static double	GaussFac, GaussAdd;
double		Gauss();
static double	numer, denom; /* Replaces use of GaussFac for precision... */

gen_mntndata(elevs, square, top)
double	**elevs, top;
int	square;
{
    MidPointFM2D(elevs,level,sigma,H,addition,(int)time((long *)0));
    scale(elevs, square, top);
}

scale(elevs, square, top)
double	**elevs;
int	square;
double	top;
{
register int	x,y;
double		max = 0.0;

    for (x=0; x<square; x++)
	for (y=0; y<square; y++)
	    if (elevs[x][y] > max)
		max = elevs[x][y];
    DEBUG(("Scaling: %f -> %f.\n",max,top));
    if (max > 0.0)			/* Just in case summat goes wrong... */
	for (x=0; x<square; x++)
	    for (y=0; y<square; y++)
		elevs[x][y] = elevs[x][y]*top/max;
}

/*==========================================================================
 * Routines 'interpreted' from the code in 'The Science Of Fractal Images.'
 *==========================================================================*/
InitGauss(seed)
int	seed;
{
    Nrand = 4;
    Arand = (1<<31)-1;		/* random() gives results in [0,Arand] */

    GaussAdd = (double)sqrt((double)(3.0*Nrand));
/* NB: GaussFac is no longer used: it loses too much precision!
 *   GaussFac = (double)(2.0 * GaussAdd / ((double)Nrand * (double)Arand));
 */
/* NB: We have to do this, as we seem to loose too much precision in the method
 *     laid out in 'The Scienc Of Fractal Images.'
 */
    numer = GaussAdd + GaussAdd;
    denom = (double)((double)Nrand * (double)Arand);

    srandom(seed);
}

double
Gauss()
{
register int	i;
register double	sum = 0;
extern long	random();

/* See the above comment in InitGauss()... */
    for (i=0; i<Nrand; i++)
	sum += (double)random();
    sum = numer*(sum/denom);
    return(sum - GaussAdd);
}

MidPointFM2D(X,maxlevel,sigma,H,addition,seed)
double	**X;
int	maxlevel;
double	sigma;
double	H;
char	addition;
int	seed;
{
register int	i, N, x,y, D,d;
double		delta;

    InitGauss(seed);
    N = 1<<maxlevel;
    DEBUG(("MidPointFM2D: (Dim:%dx%d) (Sigma:%f) (H:%f).\n",N,N,sigma,H));

    delta = sigma;
    X[0][0] = delta * Gauss();
    X[0][N] = delta * Gauss();
    X[N][0] = delta * Gauss();
    X[N][N] = delta * Gauss();

    D = N;
    d = N/2;

    for (i=0; i<maxlevel; i++) {

/* Going from Grid type I to Grid type II */
	delta = delta * pow((double)0.5,(double)(0.5*H));
	for (x=d; x<=N-d; x+=D)		/* Interpolate and offset points. */
	    for (y=d; y<=N-d; y+=D)
		X[x][y] = F4(delta,X[x+d][y+d],X[x+d][y-d],X[x-d][y+d],X[x-d][y-d]);

/* Displace other points also if needed. */
	if (addition == 1)
	    for (x=0; x<=N; x+=D)
		for (y=0; y<=N; y+=D)
		    X[x][y] = X[x][y] + delta*Gauss();

/* Going from Grid type II to Grid type I */
	delta = delta * pow(0.5,0.5*H);
/* Interpolate and offset boundary grid points. */
	for (x=d; x<=N-d; x+=D) {
	    X[x][0] = F3(delta,X[x+d][0],X[x-d][0],X[x][d]);
	    X[x][N] = F3(delta,X[x+d][N],X[x-d][N],X[x][N-d]);
	    X[0][x] = F3(delta,X[0][x+d],X[0][x-d],X[d][x]);
	    X[N][x] = F3(delta,X[N][x+d],X[N][x-d],X[N-d][x]);
	}

/* Interpolate and offset interior grid points. */
	for (x=d; x<=N-d; x+=D)
	    for (y=D; y<=N-d; y+=D)
		X[x][y] = F4(delta,X[x][y+d],X[x][y-d],X[x+d][y],X[x-d][y]);

	for (x=D; x<=N-d; x+=D)
	    for (y=d; y<=N-d; y+=D)
		X[x][y] = F4(delta,X[x][y+d],X[x][y-d],X[x+d][y],X[x-d][y]);

/* Displace other points also if needed. */
	if (addition == 1) {
	    for (x=0; x<=N; x+=D)
		for (y=0; y<=N; y+=D)
		    X[x][y] = X[x][y] + delta*Gauss();
	    for (x=d; x<=N-d; x+=D)
		for (y=d; y<=N-d; y+=D)
		    X[x][y] = X[x][y] + delta*Gauss();
	}

	D = D/2;
	d = d/2;
    }
}
SHAR_EOF
if test 4450 -ne `wc -c < 'gen_mntndata.c'`
then
    echo 'Shar: error transmitting 'gen_mntndata.c' (should have been  4450 charcaters)'
fi
fi
echo 'Shar: extracting 'cmn_mntncode.c' ( 9868 characters)'
if test -f 'cmn_mntncode.c'
then
    echo "Shar: will not overwrite existing file 'cmn_mntncode.c'"
else
    cat << \SHAR_EOF > 'cmn_mntncode.c'
/*****************************************************************************
/* FILE		: cmn_mntncode.c
/* AUTHOR	: Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
/* DATE		: July 20, 1989
/* FUNCTION	: Common code in the mountain-generating programs.
/* INSPIRATION	: 'The Science Of Fractal Images.'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include "xpt.h"

#define	RECALC		"New Mountains"
#define QUIT		"Quit"

#define PNTS(i,px,py)	{pnts[(i)].x=(px);pnts[(i)].y=(py);}

#define ABS(x)		(((x)<0) ? -(x) : (x))
#define SW(s)           (XTextWidth(fs,(s),strlen((s))))

int	screenwidth, screenheight;
int	basey;
int	square;

struct mntn {
    double	**elevs;
    int		**px;
    int		**py;
} mntndata;
extern double	sigma, H;
extern int	level;

extern char	*calloc();
extern char	*bckgrnd, *progtitle, *iconfile;

Display		*dsply;		/* The display connected to. */
Window		wndw;		/* The window in which to display */
Window		hwndw,swndw, twndw, rwndw, qwndw;
GC 		maingc, mntngc,seagc, bttngc;
unsigned long	mc;		/* Mountain colour(s?) */
Colormap	clmap;		/* colourmap for colour display. */
Pixmap		pntrbtm;
Font		fnt;
XFontStruct	*fs;
int		wdth, hght;
int		depth;		/* Display depth: no. of planes. */
int		numcols;
int		mntndist, scrndist;

static char	*titles[] = {"Brownian Motion","Mountains",
			     "Paul Sharpe @ DEC"};

extern struct opts     args[];

init_cmn()
{
    sigma = atof(ARGS(11));	/* Scaling, or standard deviation. */
    H = atof(ARGS(10));		/* Sets the fractal dimension. */
    numcols = atoi(ARGS(7));
    if ((level = atoi(ARGS(12))) < 1)
	level = 1;
    square = (1<<level) + 1;
 
    init_arrays();
}

init_arrays()
{
register int	i;

    mntndata.elevs =(double **)calloc(square,(unsigned)sizeof(double *));
    mntndata.px = (int **)calloc(square,(unsigned)sizeof(int *));
    mntndata.py = (int **)calloc(square,(unsigned)sizeof(int *));
    for (i=0; i<square; i++) {
        mntndata.elevs[i] = (double *)calloc(square,(unsigned)sizeof(double));
        mntndata.px[i] = (int *)calloc(square,(unsigned)sizeof(int));
        mntndata.py[i] = (int *)calloc(square,(unsigned)sizeof(int));
    }
}

process_events()
{
    for(;;)
	do_event();
}

do_event()
{
XEvent		event;

    XNextEvent(dsply, &event);
    switch (event.type) {
	case Expose:
	case GraphicsExpose:
	    if (event.xexpose.count == 0)
        	do_expose((XExposeEvent *)&event);
	    break;
	case ButtonPress:	/* Get a new Dimension, and redisplay! */
	    do_bttn((XButtonPressedEvent *)&event);
	    break;
	default:
	    break;
    }
}

do_expose(event)
XExposeEvent    *event;
{
    if (event->window == qwndw)
	XDrawString(dsply,qwndw,bttngc,2,fs->ascent+2,QUIT,strlen(QUIT));
    if (event->window == rwndw)
	XDrawString(dsply,rwndw,bttngc,2,fs->ascent+2,RECALC,strlen(RECALC));
    if (event->window == swndw)
	draw_scale();
    if (event->window == hwndw)
	draw_H();
    if (event->window == twndw)
	draw_titles();
    if (event->window == wndw)
	display();
}

do_bttn(bttn)
XButtonPressedEvent     *bttn;
{
    if (bttn->window == qwndw)
	exit(1);
    if (bttn->window == rwndw) {
	gen_mntndata(mntndata.elevs,square, (double)(square-5));
	elevs2coords();
	XClearWindow(dsply,wndw);
	display();
    }
    if (bttn->window == swndw) {
	if (bttn->x < 300)
	    H = (double)((double)(bttn->x)/(double)100.0);
	XClearWindow(dsply,swndw);
	XClearWindow(dsply,hwndw);
	draw_scale();
	draw_H();
    }
}

draw_face(pnts, col)
XPoint	pnts[];
int	col;		/* Colour for the filled area. */
{
int		dy;
static long	lastcol = -1;

/* Pseudo-shading determined by gradient of the face. */
    if (col >= 0 && depth > 1 && numcols > 1) {
	dy = (int)(pnts[1].y - pnts[3].y);
	col = (pnts[0].y - pnts[2].y) + (20 - ABS(dy));
        if (col >= numcols)
	    col = numcols - 1;
    }
    if (col < 0)
	col = 0;

/* Try to speed up the display by only setting colours as necessary... */
    if (col != lastcol) {
	XSetForeground(dsply,mntngc,col);
	lastcol = col;
    }
    XFillPolygon(dsply,wndw,mntngc,pnts,4,Nonconvex,CoordModeOrigin);

/* Draw the gridcolour lines around the filled quadilateral... */
    if (numcols <= 1 || depth <= 1) {
	pnts[4].x = pnts[0].x;
	pnts[4].y = pnts[0].y;
	XDrawLines(dsply,wndw,maingc,pnts,5,CoordModeOrigin);
    }
}

init_X()
{
int             x,y, len;
Font            fnt;
extern Window	xpt_window();
extern Display  *xpt_open_display();

    dsply = xpt_open_display(ARGS(0));

    depth = DEFDEPTH(dsply);

/* If we have multi-planes, allow for some shading of the mountains. */
    if (depth == 1 || numcols <= 1)
	clmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dsply));
    else {
	clmap = XCreateColormap(dsply,ROOTWNDW(dsply),DefaultVisualOfScreen(DefaultScreenOfDisplay(dsply)),AllocNone);
	set_cols(numcols);
    }
    set_GCs();

    x = screenwidth + 20;
    y = screenheight + 20;
    DEBUG(("Creating window: %dx%d.\n",x,y));
    wndw  = xpt_window(dsply,ROOTWNDW(dsply),0,0,x,y,0);
    XSetWindowColormap(dsply,wndw,clmap);
    len = DisplayWidth(dsply,DefaultScreen(dsply));
    if (x > len)
	x = len;
    xpt_windowcols(dsply,wndw,maingc,clmap,ARGS(2),"white",bckgrnd);

    init_font();

    len = SW("0.000000");
    hwndw = xpt_window(dsply,wndw,x-len-20,10,len,hght+2,ButtonPressMask);
    xpt_windowcols(dsply,hwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
    swndw = xpt_window(dsply,wndw,x-len-300-20,10,300,hght+2,ButtonPressMask);
    xpt_windowcols(dsply,swndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
    set_pointer();		/* Create a Pixmap holding the arrow pointer. */

/* BUTTON: Recalculate and draw new mountains. */
    len = SW(RECALC) + 2;
    rwndw = xpt_window(dsply,wndw,x-len-20,hght+20,len,hght+4,ButtonPressMask);
    xpt_windowcols(dsply,rwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);

/* BUTTON: Quit from mountain program. */
    len = SW(QUIT) + 2;
    qwndw = xpt_window(dsply,wndw,x-len-20,2*hght+30,len,hght+4,ButtonPressMask);
    xpt_windowcols(dsply,qwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);

/* Title block for the mountains, author etc. */
    len = XTextWidth(fs,titles[2],strlen(titles[2])) + 4;
    twndw = xpt_window(dsply,wndw,10,10,len,3*hght+4,ButtonPressMask);
    xpt_windowcols(dsply,twndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);

    XMapSubwindows(dsply,wndw);
    XMapWindow(dsply,wndw);

    xpt_icon(dsply,wndw,progtitle,iconfile);
}

init_font()
{
    fnt = XLoadFont(dsply,ARGS(9));
    XSetFont(dsply,bttngc,fnt);
    fs = XQueryFont(dsply,fnt);
    wdth = fs->max_bounds.width;
    hght = 2 + fs->ascent + fs->descent;
}

set_GCs()
{
    maingc = XDefaultGC(dsply,DefaultScreen(dsply));
    XSetFunction(dsply,maingc,GXcopy);
    XSetPlaneMask(dsply,maingc,AllPlanes);
    XSetGraphicsExposures(dsply,maingc,True);
    XSetForeground(dsply, maingc, xpt_colour(dsply,ARGS(1),clmap));
    XSetBackground(dsply, maingc, xpt_colour(dsply,ARGS(2),clmap));

    bttngc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
    XCopyGC(dsply,maingc,-1L,bttngc);
    XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(3),clmap));
    XSetBackground(dsply, bttngc, xpt_colour(dsply,ARGS(4),clmap));

    seagc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
    XCopyGC(dsply,maingc,-1L,seagc);
    XSetForeground(dsply, seagc, xpt_colour(dsply,ARGS(5),clmap));

    mntngc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
    XCopyGC(dsply,maingc,-1L,mntngc);
    XSetForeground(dsply, mntngc,(mc = xpt_colour(dsply,ARGS(6),clmap)));
}

set_cols(numcols)
int	numcols;
{
int		i, dc;
char		str[32], fmt[32];
extern char	*index();

/* Spread the colours out along the available spectrum... */
    sprintf(fmt,"#%s%s%s",(index(ARGS(8),'r')==NULL)?"0000":"%04x",
			  (index(ARGS(8),'g')==NULL)?"0000":"%04x",
			  (index(ARGS(8),'b')==NULL)?"0000":"%04x");
    if (numcols > 1) {
	dc = 65000/numcols;
	for (i=1; i<=numcols; i++) {
	    sprintf(str,fmt,i*dc,i*dc,i*dc);
	    xpt_colour(dsply,str,clmap);
	}
    }
}

draw_titles()
{
int	i, y;

    for (i=0; i<3; i++) {
	y = i*hght + fs->ascent + 1;
	XDrawString(dsply,twndw,bttngc,2,y,titles[i],strlen(titles[i]));
    }
}

draw_scale()
{
int	x, i;

    for (i=100; i<=200; i+=100) {
	XDrawLine(dsply,swndw,bttngc,i,0,i,5);
	XDrawLine(dsply,swndw,bttngc,i,hght,i,hght-5);
    }
    XDrawLine(dsply,swndw,bttngc,300,0,300,hght);
    x = (int)floor(H * (double)100.0) - (hght/2);
    XCopyArea(dsply,pntrbtm,swndw,bttngc,0,0,hght,hght,x,0);
}

draw_H()
{
char	str[16];

    sprintf(str,"%f",H);
    XDrawString(dsply,hwndw,bttngc,2,fs->ascent+2,str,strlen(str));
}

set_pointer()
{
XPoint	pnts[7];

    pntrbtm = XCreatePixmap(dsply,wndw,hght,hght,depth);
    if (pntrbtm == 0) {
	fprintf(stderr,"FATAL: Can't create pointer pixmap!\n");
	exit(2);
    }
/* Set the foreground to the normal button text background colour. */
    XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(4),clmap));
/* Clear the Pixmap by filling it as a rectangle with the background colour. */
    XFillRectangle(dsply, pntrbtm,bttngc,0,0,hght,hght);
/* Reset the normal button text foreground colour. */
    XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(3),clmap));
    pnts[0].x = hght/2;		pnts[0].y = 0;
    pnts[1].x = 0;		pnts[1].y = hght/2;
    pnts[2].x = hght/4;		pnts[2].y = pnts[1].y;
    pnts[3].x = pnts[2].x;	pnts[3].y = hght;
    pnts[4].x = 3*hght/4;	pnts[4].y = pnts[3].y;
    pnts[5].x = pnts[4].x;	pnts[5].y = pnts[1].y;
    pnts[6].x = hght;		pnts[6].y = pnts[5].y;
    XFillPolygon(dsply,pntrbtm,bttngc,pnts,7,Nonconvex,CoordModeOrigin);
}
SHAR_EOF
if test 9868 -ne `wc -c < 'cmn_mntncode.c'`
then
    echo 'Shar: error transmitting 'cmn_mntncode.c' (should have been  9868 charcaters)'
fi
fi
echo 'Shar: extracting 'xmntn.c' ( 5582 characters)'
if test -f 'xmntn.c'
then
    echo "Shar: will not overwrite existing file 'xmntn.c'"
else
    cat << \SHAR_EOF > 'xmntn.c'
/*****************************************************************************
/* FILE		: xmntn.c
/* AUTHOR	: Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
/* DATE		: July 20, 1989
/* FUNCTION	: X-windows Fractal Brownian-Motion mountains.
/* INSPIRATION	: 'The Science Of Fractal Images.'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include "xpt.h"
#include "xmntn.h"

main(argc,argv)
int	argc;
char	*argv[];
{
    xpt_getargs(args,NUMARGS,argc,argv);
    init();
    gen_mntndata(mntndata.elevs,square, (double)(yscale*square - 5));
    elevs2coords();
    process_events();			/* Main event-processing loop. */
}

init()
{
    init_cmn();
    if ((xscale = atoi(ARGS(13))) < 1)
        xscale = 1;
    if ((yscale = atoi(ARGS(14))) < 1)
        yscale = 1;
    screenwidth  = square*(xscale*2)+(XOFFSET*3);
    screenheight = square*yscale*3;
    basey = yscale*3*square;
    init_X();
}

elevs2coords()
{
register int	i,j, x,y, rowy;

    DEBUG(("Converting elevations to Y-coordinates..."));

/* To speed up, convert elevations for those points having the same Y-pixel
 * coordinate: i.e. those points on the diagonals.
 */
    for (i=0; i<square; i++) {
	rowy = PIXELY(i,0) - HEIGHT;
	for (j=0; j<=i; j++) {
	    x = i - j;
	    y = j;
	    mntndata.px[x][y] = PIXELX(x,y);
	    mntndata.py[x][y] = rowy - ((mntndata.elevs[x][y] <= (double)0.0)? 0:(int)floor(mntndata.elevs[x][y]));
	}
    }
    for (i=1; i<square; i++) {
	rowy = PIXELY(square-1,i) - HEIGHT;
	for (j=square-1; j>=i; j--) {
	    x = j;
	    y = i + square - j - 1;
	    mntndata.px[x][y] = PIXELX(x,y);
	    mntndata.py[x][y] = rowy - ((mntndata.elevs[x][y] <= (double)0.0)? 0:(int)floor(mntndata.elevs[x][y]));
	}
    }
    DEBUG(("DONE\n"));
}

display()
{
    draw_grid();
    draw_heights();
}

draw_grid()
{
register int	i;
static XPoint	pnts[6];

/* Colour the main grid ('the sea') polygon. */
    PNTS(0, PIXELX(square-1,square-1),	PIXELY(square-1,square-1));
    PNTS(1, PIXELX(square-1,0),		PIXELY(square-1,0));
    PNTS(2, pnts[1].x,			pnts[1].y - HEIGHT);
    PNTS(3, pnts[0].x,			PIXELY(0,0) - HEIGHT);
    PNTS(4, PIXELX(0,square-1),		pnts[2].y);
    PNTS(5, pnts[4].x,			pnts[1].y);
    XFillPolygon(dsply,wndw,seagc,pnts,6,Nonconvex,CoordModeOrigin);
    
    for (i=0; i<square; i++) {
	PNTS(0, PIXELX(square-1, i),	PIXELY(square-1, i));
	PNTS(1, pnts[0].x,		pnts[0].y - HEIGHT);
	PNTS(2, PIXELX(0, i),		PIXELY(0, i) - HEIGHT);
	XDrawLines(dsply,wndw,maingc,pnts,3,CoordModeOrigin);

	PNTS(0, PIXELX(i, square-1),	PIXELY(i, square-1));
	PNTS(1, pnts[0].x,		pnts[0].y - HEIGHT);
	PNTS(2, PIXELX(i, 0),		PIXELY(i, 0) - HEIGHT);
	XDrawLines(dsply,wndw,maingc,pnts,3,CoordModeOrigin);
    }

/* Bottom two lines of the block. */
    PNTS(0, PIXELX(0,square-1),		PIXELY(0,square-1));
    PNTS(1, PIXELX(square-1,square-1),	PIXELY(square-1,square-1));
    PNTS(2, PIXELX(square-1,0),		PIXELY(square-1,0));
    XDrawLines(dsply,wndw,maingc,pnts,3,CoordModeOrigin);
}

/******************************************************************************
 * Fill the quadilateral faces along lines parallel to a far edge.
 ******************************************************************************/
draw_heights()
{
register int	x,y;
static XPoint	pnts[4];

    for (x=0; x<square; x++)
	for (y=0; y<square; y++)
	    if (x>0 && y>0)
		if (mntndata.elevs[x][y] > 0   || mntndata.elevs[x-1][y] > 0 ||
		    mntndata.elevs[x][y-1] > 0 || mntndata.elevs[x-1][y-1] > 0){
		    PNTS(0, mntndata.px[x][y],    mntndata.py[x][y]);
		    PNTS(1, mntndata.px[x][y-1],  mntndata.py[x][y-1]);
		    PNTS(2, mntndata.px[x-1][y-1],mntndata.py[x-1][y-1]);
		    PNTS(3, mntndata.px[x-1][y],  mntndata.py[x-1][y]);
		    draw_face(pnts,mc);
		}
}

#ifdef NOTUSED
/******************************************************************************
 * Fill the quadilateral faces along diagonal lines (parallel to the viewer).
 ******************************************************************************/
heights_by_diagonal()
{
register int	x,y;
static XPoint	pnts[5];

/* Top diagonal half of the complete square. */
    for (i=0; i<square; i++) {
	for (j=0; j<=i; j++) {
	    if ((x = i - j) > 0 && (y = j) > 0)
		if (mntndata.elevs[x][y] > 0   || mntndata.elevs[x-1][y] > 0 ||
		    mntndata.elevs[x][y-1] > 0 || mntndata.elevs[x-1][y-1] > 0){
		    PNTS(0, mntndata.px[x][y],    mntndata.py[x][y]);
		    PNTS(1, mntndata.px[x-1][y],  mntndata.py[x-1][y]);
		    PNTS(2, mntndata.px[x-1][y-1],mntndata.py[x-1][y-1]);
		    PNTS(3, mntndata.px[x][y],  mntndata.py[x][y]);
		    draw_face(pnts,mc);
		}
	}
    }

/* Bottom diagonal half of the complete square. */
    for (i=1; i<square; i++) {
	for (j=square-1; j>=i; j--) {
	    if ((x = j) > 0 && (y = i + square - j - 1) > 0)
		if (mntndata.elevs[x][y] > 0   || mntndata.elevs[x-1][y] > 0 ||
		    mntndata.elevs[x][y-1] > 0 || mntndata.elevs[x-1][y-1] > 0){
		    PNTS(0, mntndata.px[x][y],    mntndata.py[x][y]);
		    PNTS(1, mntndata.px[x-1][y],  mntndata.py[x-1][y]);
		    PNTS(2, mntndata.px[x-1][y-1],mntndata.py[x-1][y-1]);
		    PNTS(3, mntndata.px[x][y],  mntndata.py[x][y]);
		    draw_face(pnts,mc);
		}
	}
    }
}
#endif
SHAR_EOF
if test 5582 -ne `wc -c < 'xmntn.c'`
then
    echo 'Shar: error transmitting 'xmntn.c' (should have been  5582 charcaters)'
fi
fi
echo 'Shar: extracting 'xlmntn.c' ( 2897 characters)'
if test -f 'xlmntn.c'
then
    echo "Shar: will not overwrite existing file 'xlmntn.c'"
else
    cat << \SHAR_EOF > 'xlmntn.c'
/*****************************************************************************
/* FILE		: xlmntn.c
/* AUTHOR	: Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
/* DATE		: July 20, 1989
/* FUNCTION	: X-windows Fractal Brownian-Motion mountains.
/* INSPIRATION	: 'The Science Of Fractal Images.'
/*
/*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
/*   Copyright is claimed in the computer program and user interface thereof.
/*
/*   Digital Equipment Corporation cannot accept any responsibility for
/*   use, misuse, or abuse of this software.
/*
/*****************************************************************************/

#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include "xpt.h"
#include "xlmntn.h"

main(argc,argv)
int	argc;
char	*argv[];
{
    xpt_getargs(args,NUMARGS,argc,argv);
    init();
    gen_mntndata(mntndata.elevs,square, (double)(square-5));
    elevs2coords();
    process_events();			/* Main event-processing loop. */
}

init()
{
    init_cmn();
    obsheight = atoi(ARGS(13));
    if ((mntndist = atoi(ARGS(13))) < 1)
	mntndist = 200;
    if ((scrndist = atoi(ARGS(14))) < 1)
	scrndist = 2000;
    screenwidth = square*scrndist/mntndist;
    screenheight= screenwidth;
    zeroy = screenheight - obsheight*scrndist/mntndist;
    init_X();
}

elevs2coords()
{
register int	x,y;

    basey = square;
    DEBUG(("Converting elevations to Y-coordinates...\n"));

    for (y=0; y<square; y++) {
	for (x=0; x<square; x++) {
	    if (mntndata.elevs[x][y] <= 0.0)
		mntndata.elevs[x][y] = 0.000000;
	    mntndata.px[x][y] = PIXELX(x,y);
	    mntndata.py[x][y] = PIXELY(x,y,(int)floor(mntndata.elevs[x][y]));
	}
    }
}

display()
{
    draw_grid();
    draw_heights();
}

draw_grid()
{
XPoint	pnts[4];

/* Colour the main grid ('the sea') polygon. */
    PNTS(0, PIXELX(0,0),	   PIXELY(0,0,0));
    PNTS(1, PIXELX(square,0),	   PIXELY(square,0,0));
    PNTS(2, PIXELX(square,square), PIXELY(square,square,0));
    PNTS(3, PIXELX(0,square),	   PIXELY(0,square,0));
    XFillPolygon(dsply,wndw,seagc,pnts,4,Nonconvex,CoordModeOrigin);
}

draw_heights()
{
register int	x,y;
XPoint		pnts[5];

    for (y=square-1; y>=0; y--) {
	for (x=0; x<square; x++) {
	    if (y < square-1 && x > 0) {
		if (mntndata.elevs[x][y] > 0   || mntndata.elevs[x-1][y] > 0 ||
		    mntndata.elevs[x][y+1] > 0 || mntndata.elevs[x-1][y+1] >0) {

		    PNTS(0, mntndata.px[x][y],     mntndata.py[x][y]);
		    PNTS(1, mntndata.px[x-1][y],   mntndata.py[x-1][y]);
		    PNTS(2, mntndata.px[x-1][y+1], mntndata.py[x-1][y+1]);
		    PNTS(3, mntndata.px[x][y+1]  , mntndata.py[x][y+1]);
		    draw_face(pnts, mc);

		    if (y == 0) {
			PNTS(2, mntndata.px[x-1][y], PIXELY(x-1,y,0));
			PNTS(3, mntndata.px[x][y]  , PIXELY(x  ,y,0));
			draw_face(pnts, -1);
		    }
		} /* if elevs... */
	    } /* if y */
	}
    }
}
SHAR_EOF
if test 2897 -ne `wc -c < 'xlmntn.c'`
then
    echo 'Shar: error transmitting 'xlmntn.c' (should have been  2897 charcaters)'
fi
fi
echo 'Shar: extracting 'bg.btm' ( 93 characters)'
if test -f 'bg.btm'
then
    echo "Shar: will not overwrite existing file 'bg.btm'"
else
    cat << \SHAR_EOF > 'bg.btm'
#define bg_width 4
#define bg_height 4
static char bg_bits[] = {
   0x05, 0x05, 0x05, 0x05};
SHAR_EOF
if test 93 -ne `wc -c < 'bg.btm'`
then
    echo 'Shar: error transmitting 'bg.btm' (should have been  93 charcaters)'
fi
fi
echo 'Shar: extracting 'mntn.btm' ( 3319 characters)'
if test -f 'mntn.btm'
then
    echo "Shar: will not overwrite existing file 'mntn.btm'"
else
    cat << \SHAR_EOF > 'mntn.btm'
#define mntn_width 64
#define mntn_height 64
#define mntn_x_hot -1
#define mntn_y_hot -1
static char mntn_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x7f,
   0xfe, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x1f, 0x7f, 0xfe, 0xff, 0xbf, 0xf1,
   0xff, 0xff, 0x4f, 0x7c, 0xfe, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x7d,
   0xfe, 0xff, 0x6f, 0xfe, 0xff, 0x7f, 0xfe, 0x61, 0xfe, 0xff, 0xe3, 0xfc,
   0xff, 0x3f, 0xff, 0x5b, 0xfe, 0xff, 0xf8, 0xfd, 0xff, 0x1f, 0xff, 0x5f,
   0xfe, 0xff, 0xfe, 0xf9, 0xff, 0xdf, 0xff, 0x5f, 0xfe, 0x7f, 0xfe, 0xfb,
   0xff, 0xdf, 0xff, 0x47, 0xfe, 0x3f, 0xff, 0xf7, 0x7f, 0x1e, 0x00, 0x70,
   0xfe, 0x9f, 0xff, 0xf7, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xcf, 0xff, 0xef,
   0x3f, 0xfd, 0xff, 0x4f, 0xfe, 0x87, 0xff, 0xcf, 0x9f, 0xf9, 0xff, 0x0f,
   0xfe, 0x07, 0xff, 0x9f, 0xcf, 0xf3, 0xff, 0x27, 0xfe, 0x03, 0xfe, 0x3f,
   0xe7, 0xf7, 0xff, 0x73, 0xfe, 0x81, 0xf8, 0x7f, 0xf1, 0xf7, 0xff, 0x7b,
   0xfe, 0x40, 0xf1, 0x7f, 0xfc, 0xe7, 0xff, 0x79, 0x7e, 0xa0, 0xe2, 0xff,
   0xfe, 0x8f, 0xff, 0x7c, 0x7e, 0x40, 0xc5, 0xf8, 0xfc, 0xbf, 0x7f, 0x7c,
   0x3e, 0xa0, 0x0a, 0xf0, 0x79, 0x0c, 0x3f, 0x71, 0x3e, 0x50, 0x55, 0xe5,
   0x18, 0x00, 0x8e, 0x06, 0x1e, 0xa8, 0xaa, 0x0a, 0x00, 0x00, 0x44, 0x15,
   0x0e, 0x54, 0x54, 0x55, 0x15, 0x00, 0xa0, 0x2a, 0x06, 0x2a, 0xa8, 0xaa,
   0x0a, 0x00, 0x50, 0x55, 0x06, 0x55, 0x50, 0x55, 0x15, 0x00, 0xa0, 0x2a,
   0x82, 0x22, 0xa0, 0xa0, 0x2a, 0x00, 0x00, 0x55, 0x40, 0x55, 0x50, 0x51,
   0x55, 0x00, 0x00, 0x28, 0x80, 0x2a, 0xa8, 0xa2, 0xaa, 0x00, 0x00, 0x50,
   0x40, 0x11, 0x50, 0x01, 0x45, 0x01, 0x00, 0x20, 0x80, 0xa8, 0xa8, 0x8a,
   0xa2, 0x02, 0x00, 0x60, 0x40, 0x51, 0x14, 0x54, 0x15, 0x05, 0x00, 0x00,
   0xa0, 0x28, 0x2a, 0x8a, 0x22, 0x0a, 0x00, 0x00, 0x50, 0x14, 0x50, 0x15,
   0x55, 0x15, 0x00, 0x00, 0xa8, 0xa8, 0xa2, 0x2a, 0xaa, 0x2a, 0x00, 0x00,
   0x04, 0x54, 0x51, 0x55, 0x15, 0x50, 0x00, 0x00, 0x28, 0xaa, 0x00, 0x2a,
   0x0a, 0xa2, 0x00, 0x00, 0x44, 0x55, 0x00, 0x14, 0x15, 0x45, 0x01, 0x00,
   0xa8, 0x0a, 0x02, 0x2a, 0xaa, 0x8a, 0x02, 0x00, 0x44, 0x40, 0x11, 0x55,
   0x55, 0x05, 0x05, 0x00, 0x8a, 0x82, 0x00, 0x2a, 0xa8, 0xaa, 0x0a, 0x00,
   0x54, 0x51, 0x50, 0x55, 0x51, 0x11, 0x10, 0x00, 0x8a, 0x0a, 0x28, 0xa8,
   0x22, 0xa0, 0x22, 0x00, 0x44, 0x45, 0x54, 0x55, 0x05, 0x40, 0x45, 0x00,
   0x0a, 0x2a, 0xaa, 0xa0, 0x8a, 0x82, 0xaa, 0x00, 0x04, 0x55, 0x50, 0x41,
   0x55, 0x51, 0x05, 0x01, 0x22, 0xaa, 0x0a, 0xa2, 0xa8, 0x88, 0x2a, 0x02,
   0x54, 0x50, 0x41, 0x51, 0x51, 0x41, 0x54, 0x04, 0xaa, 0xaa, 0xaa, 0xaa,
   0xa2, 0x02, 0xaa, 0x0a, 0x54, 0x55, 0x55, 0x55, 0x55, 0x45, 0x40, 0x10,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x2a, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x45, 0x51, 0x51, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x02, 0xa0, 0x22,
   0xfa, 0x7a, 0x01, 0xbd, 0x31, 0x55, 0x44, 0x55, 0x72, 0x72, 0xef, 0xb9,
   0x2e, 0x2a, 0x88, 0x22, 0xaa, 0x6a, 0xef, 0xb5, 0x3e, 0x15, 0x45, 0x51,
   0xaa, 0x6a, 0xef, 0xb5, 0x31, 0xaa, 0xa8, 0x22, 0xda, 0x5a, 0xef, 0xad,
   0x2f, 0x15, 0x54, 0x45, 0xda, 0x5a, 0xef, 0xad, 0x2f, 0x0a, 0x22, 0x02,
   0xfa, 0x3a, 0xef, 0x9d, 0x2e, 0x55, 0x01, 0x45, 0xfa, 0x7a, 0xef, 0xbd,
   0x31, 0xaa, 0xa8, 0x2a, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x55, 0x55, 0x55,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
SHAR_EOF
if test 3319 -ne `wc -c < 'mntn.btm'`
then
    echo 'Shar: error transmitting 'mntn.btm' (should have been  3319 charcaters)'
fi
fi
